class Transaction1sController < ApplicationController




auto_complete_for :account, :name
  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
  verify :method => :post, :only => [ :destroy, :create, :update ],
         :redirect_to => { :action => :list }

     def index
    list
    render :action => 'list'
    end


    def signed_accounts(transactions)
        i=0
        for transaction in transactions
        
            if ["libialities","incomes","wealth"].index(transaction.account.category)
                transactions[i].amount=-transactions[i].amount   
            end
        i=i+1 
        end        
        return transactions
    end    


    def balance_sheet(period,optional)
        balance_sheet=GeneralBalaceSheet.find_by_sql ["SELECT account_id,total_amount  FROM general_balace_sheets where period =? "+ optional,period]
        return balance_sheet
    end    
    

    def total_accounts_in_a_period(period,optional)
        #Finds the total of an account group by the account_id
        
        total_accounts_period=Transaction1.find_by_sql ["select A1.account_id  , sum(A1.amount )as amount from transaction1s as A1 where A1.period_id=? "+optional+" GROUP BY(A1.account_id)",period]
        #signed_accounts( total_accounts_period)
        return total_accounts_period     
    end
    


    def new_balance_sheet_cell(account_id,period,amount)
        total=Hash.new()
        total["account_id"]=account_id
        total["period"]=period
        total["total_amount"]=amount
        new_total=GeneralBalaceSheet.new(total)
        new_total.save()
    end    

    def account_id4code(code)

        account=Transaction1.find_by_sql ["Select id from accounts where  code=?", code]
        return account[0].id

    end    





 
    def sum_account(list)
        total=0
        for i in list
           total= total+i.amount.to_f
       end    
       
       return total
    end   
 
    def account_code4name(name)
       
        answer=Transaction1.find_by_sql ["Select code from accounts where  name=?", name]
       
        return answer[0].code
        
    end
    
    def account_code4id(account_id)
        account=Transaction1.find_by_sql ["Select code from accounts where  account_id=?", account_id]
        return account[0].code
    end        
    

    def update_old_utilities(period)

        #utilidades acumuladas 3705, account_id 284
        #utilidades actuales 3605, account_id 276
        past_utilities_id=account_id4code("3705").to_s
        last_utility_id=account_id4code("3605").to_s
        past_utilities=balance_sheet(period.to_i,"and account_id="+past_utilities_id)
        last_utility=balance_sheet(period.to_i,"and account_id="+last_utility_id)

        if !past_utilities.blank? 
            past_utilities[0].total_amount=past_utilities[0].total_amount   
            if !last_utility.blank?
                past_utilities[0].total_amount= past_utilities[0].total_amount+last_utility[0].total_amount  
            end    
            GeneralBalaceSheet.delete_all("period="+period.to_s+" and account_id="+last_utility_id)
            GeneralBalaceSheet.delete_all("period="+period.to_s+" and account_id="+past_utilities_id)
            new_balance_sheet_cell(past_utilities_id,period,past_utilities[0].total_amount)

        else
            new_balance_sheet_cell(past_utilities_id,period,0)
        end    

    end


        

    def new_utility(period)
        # Calculates and save the new utility for the period
        
        #Utitlidad del ejericio 3605
        incomes=total_accounts_in_a_period(period,"and A1.account_id in (select id from accounts where category='incomes')")
        expenses=total_accounts_in_a_period(period,"and A1.account_id in (select id from accounts where category= 'expenses')")
        period_utility=0
        if !incomes.blank?
            a=sum_account(incomes)
            period_utility= sum_account(incomes)
        end
        if !expenses.blank?
            b=sum_account(expenses)
            period_utility=period_utility-sum_account(expenses)
        end
        new_utility_id=account_id4code("3605")
        new_balance_sheet_cell(new_utility_id,period,period_utility)
    end    
    def to_close 
        info
        period=params[:period] 
        
        #We need create a new hash for save the new created balance sheet
        # Get all current transaction cateogoryzed by assets, liabilities and  wealth
        
        #Deletes depreciations
        Transaction1.delete_all("account_id="+account_id4code("1592").to_s+" or account_id="+account_id4code("5260").to_s+" and period_id="+period.to_s()) 
        #Deletes current Geneal Balance sheet if it exists

        GeneralBalaceSheet.delete_all("period="+period.to_s())    

        new_depreciation(period)  
        transactions=total_accounts_in_a_period(period,"and A1.account_id in (select id from accounts where (category='assets' or category='liabilities' or  category='wealth'))")
        #Found latest balance sheet cells 
        total_accumulate=balance_sheet(period.to_i-1,"")
        
        #First, we must calculates the depreciations for fixed assets 

        # We save the newest accumulates
        for  transaction in transactions
            i=0
            for accumulate in  total_accumulate
                if transaction.account_id.to_i()==accumulate.account_id.to_i()
                        transaction.amount=transaction.amount.to_f+accumulate.total_amount.to_f
                        #Total accumulate is an array, we just get out the oldest account beacause we are adding with the newest accumulate
                        total_accumulate.slice!(i)
                end      
                i=i+1    
            end
            new_balance_sheet_cell(transaction.account_id,period,transaction.amount) 
        end

        # And the sum  with the oldest accounts
        for accumulate in  total_accumulate
            
             new_balance_sheet_cell(accumulate.account_id,period,accumulate.total_amount)
             
        end    
        
        
        #Updates old utilities
        update_old_utilities(period)
        # Creates a new utility
        new_utility(period)
        redirect_to :controller=>"periods",:action=>"list"
    end    
    
    def validate_period
        period=Period.find(params[:period])
        debit=sum_account(total_accounts_in_a_period(period.id,"and A1.account_id in (select id from accounts where (category='assets' or category='expenses'))"))
        credit=sum_account(total_accounts_in_a_period(period.id,"and A1.account_id in (select id from accounts where (category='incomes' or category='liabilities' or  category='wealth'))"))
        total=debit-credit
        
        if total==0
             period.valid="VALID"
        else
            period.valid="INVALID"
        end

        period.save()
        
        redirect_to :controller=>params[:redirect],:action=>"list",:period=>period

    end

    def total_amount_period_transactions
        period=params[:period] 
        @period=period

=begin

    This view show the total amount of the transactions in a period
    
    

=end
        @total=Transaction1.find_by_sql ["SELECT B.code,A.account_id, B.name, sum( A.amount ) AS cash_flow, C.total_amount AS initial_amount FROM (transaction1s  as A JOIN accounts AS B ) LEFT JOIN general_balace_sheets as C on (C.period=? and A.account_id=C.account_id) WHERE  A.period_id =? and A.account_id=B.id GROUP BY (A.account_id) order by B.code ",period.to_i-1,period]  
        i=0
        for t in @total
            @total[i][:transactions]=Transaction1.find(:all,:conditions=>["account_id=? and period_id=?",t[:account_id],period],:order=>"date")
            i=i+1
        end    

        info
        
    
    end    

    def show_income_statement
        @period=params[:period] 
=begin
        Create a new hash por result state view

        This hash has to containt these information

        Operational incomes              -
        No operational incomes
        Operational Expenses        -Colombia code 51% 52% 
        No operational Expenses     - Colombia 530%
=end   
        total=Hash.new()
        total[:operational_revenue]=Transaction1.find_by_sql ["select B.name,  sum(A.amount )as amount from transaction1s as A, accounts as B where A.account_id=B.id and A.period_id=? and  B.category='incomes' and code like '41%'   GROUP BY(A.account_id) order by B.code",@period]
        total[:t_operational_revenue]=sum_account(total[:operational_revenue])        
        total[:operational_expenses]=Transaction1.find_by_sql ["select B.name,  sum(A.amount )as amount from transaction1s as A, accounts as B where A.account_id=B.id and A.period_id=? and  B.category='expenses' and (code like '51%' or code like '52%')   GROUP BY(A.account_id) order by B.code",@period]
        total[:t_operational_expenses]=sum_account(total[:operational_expenses])
        total[:no_operational_revenue]=Transaction1.find_by_sql ["select B.name,  sum(A.amount )as amount from transaction1s as A, accounts as B where A.account_id=B.id and A.period_id=? and  B.category='incomes'  and code like '42%' GROUP BY(A.account_id) order by B.code",@period]
        total[:t_no_operational_revenue]=sum_account(total[:no_operational_revenue])       
        total[:no_operational_expenses]=Transaction1.find_by_sql ["select B.name,  sum(A.amount )as amount from transaction1s as A, accounts as B where A.account_id=B.id and A.period_id=? and  B.category='expenses' and code like '530%'    GROUP BY(A.account_id) order by B.code",@period]
        total[:t_no_operational_expenses]=sum_account(total[:no_operational_expenses])
        total[:tax]=0.385 # 38 %percent
        total[:operative_profit]=total[:t_operational_revenue]-total[:t_operational_expenses]    
        total[:earnings_before_taxes]=total[:operative_profit]+total[:t_no_operational_revenue]-total[:t_no_operational_expenses]
        total[:taxes]=total[:earnings_before_taxes]*total[:tax]
        total[:net_income]=total[:earnings_before_taxes]-total[:taxes]  
        @total=total
        info


    end    


    def view_balance_sheet
        # Reads a general balance sheet
        info
        @period=params[:period] 
        total=Hash.new()
        total[:assets]=GeneralBalaceSheet.find_by_sql ["SELECT B.name,A.total_amount as amount FROM general_balace_sheets as A, accounts as B  where A.period =? and A.account_id=B.id and B.category='assets' order by B.code",@period]
        total[:total_assets]=sum_account(total[:assets])
        total[:liabilities]=GeneralBalaceSheet.find_by_sql ["SELECT B.name,A.total_amount as amount  FROM general_balace_sheets as A, accounts as B  where A.period =? and A.account_id=B.id and B.category='liabilities' order by B.code",@period]
        total[:total_liabilities]=sum_account(total[:liabilities])
        total[:wealth]=GeneralBalaceSheet.find_by_sql ["SELECT B.name,A.total_amount as amount FROM general_balace_sheets as A, accounts as B  where A.period =? and A.account_id=B.id and B.category='wealth' order by B.code",@period]
        total[:total_wealth]=sum_account(total[:wealth])
        @total=total
    end

    def new_transaction(account_id,period,date,amount,subject)
        total_depreciation=Hash.new()
        total_depreciation[:account_id]=account_id    
        total_depreciation[:period_id]=period
        total_depreciation[:date]=date
        total_depreciation[:amount]=amount
        total_depreciation[:subject]=subject 
        transaction=Transaction1.new(total_depreciation)
        transaction.save
        return total_depreciation
       
    end    

    def depreciation_amount(transaction,selected)
        if selected=="days"
            days=30*@accounting_cycle.to_i-transaction.date.day

            dep_amount=transaction.amount.to_f/transaction.age.to_i/360*days

        else
            dep_amount=transaction.amount.to_f/transaction.age.to_i/12*@accounting_cycle.to_i
        end   
        return dep_amount
        
    end    

    def new_depreciation(period)
=begin

    Calculates the respective depreciation for a account
    1592 Correoind 

=end
        transactions=Transaction1.find_by_sql ["SELECT A.account_id,A.date,A.amount,C.live_years as age from transaction1s as A, accounts as B , depreciations as C  where  A.account_id=B.id and B.code=C.code and A.period_id=?",period]
        accumulated_transactions=GeneralBalaceSheet.find_by_sql ["SELECT A.account_id,A.total_amount as amount,C.live_years as age from general_balace_sheets as A, accounts as B , depreciations as C  where  A.account_id=B.id and B.code=C.code and A.period=?",period.to_i-1]
        dep_amount=0

        for transaction in transactions
            dep_amount=dep_amount+depreciation_amount(transaction,"days")
        end

        for transaction in accumulated_transactions
            dep_amount=dep_amount+depreciation_amount(transaction,"accounting_cycle")
        end    

        account_id=account_id4code("1592")
        new_transaction(account_id,period,"",-dep_amount,"Depreciacion acumulada")
        #new_balance_sheet_cell(account_id,period,-dep_amount)
        account_id=account_id4code("5260")
        new_transaction(account_id,period,"",dep_amount,"Gastos depreciacion")


        
        #Currents expenses by depreciation

    end    

    def info
=begin        
    
Returns some information about bussiness

=end  
 
        config = Configuration.find :first 
        @business_title=config.business_title 
        @foundation_date= config.foundation_date
        @accounting_cycle=config.months_accounting_cycle
    
    end     
         
  def list
    info
    @period=params[:period]
    @transaction1_pages, @transaction1s = paginate :transaction1s, :per_page => 30,:conditions=>["period_id =?",@period],:order=>"date ASC"

  end

  def show
    @transaction1 = Transaction1.find(params[:id])#, :order_by=>"date")
  end

  def new
    info  
    @year=@foundation_date.year()+(@accounting_cycle.to_i)/12
    @month=@accounting_cycle.to_i-12*(@accounting_cycle.to_i/12)
    @day=1
    @transaction1 = Transaction1.new
  end

  def create
    
    transaction=params[:transaction1]
    name=params[:account].fetch("name")
    account=Account.find(:first, :conditions =>["name=?",name])
    transaction[:account_id]=account.id
    @transaction1 = Transaction1.new(transaction)
    @period=params[:transaction1].fetch("period_id")
    if @transaction1.save
      flash[:notice] = 'La transacci&oacute;n se registr&oacute; correctamente'
      redirect_to :action => 'list', :period=>@period
    else
      render :action => 'new',:period=>@period
    end
  end

  def edit
    @transaction1 = Transaction1.find(params[:id])
  end

  def update
    transaction=params[:transaction1]
    name=params[:account].fetch("name")
    account=Account.find(:first, :conditions =>["name =?",name])
    
    transaction[:account_id]=account.id
    @period=params[:transaction1].fetch("period_id")
    @transaction1 = Transaction1.find(params[:id])
    if @transaction1.update_attributes(params[:transaction1])
      flash[:notice] = 'La transacci&oacute;n se actualiz&oacute; correctamente'
      redirect_to :action => 'show', :id => @transaction1,:period=>@period
    else
      render :action => 'edit',:period=>@period
    end
end




  def destroy
    Transaction1.find(params[:id]).destroy
    @period=params[:period]
    redirect_to :action => 'list',:period=>@period
  end
end
